package tech.jdbc.dao.impl;

import tech.jdbc.dao.IEmpDao;
import tech.jdbc.entity.Emp;
import tech.jdbc.util.JdbcUtil;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Create with Intellij IDEA
 *
 * @Author Q
 * @date 2021/11/25/10:39
 */
public class EmDaoImpl implements IEmpDao {
    @Override
    public Emp getByName(String name) {
        //sql注入问题
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        Emp emp = null;
        String url="jdbc:mysql://localhost:3306/baby";
        String user = "root";
        String password = "root";
        try {
            conn = DriverManager.getConnection(url,user,password);
            st = conn.createStatement();
            //select * from s_emp where first_name = 'Carmen';
            String sql = "select id,first_name,salary from s_emp where first_name='"+name+"'";

            System.out.println(sql);

            rs = st.executeQuery(sql);

            if(rs.next()){
                emp = new Emp();//初始化这个对象 - 存储数据

                Integer id = rs.getInt(1);
                String firstName = rs.getString(2);
                double salary = rs.getDouble(3);

                emp.setId(id);
                emp.setFirstName(firstName);
                emp.setSalary(salary);

            }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //6. 释放资源
            //无论try块中是否出现异常,都会执行,一般适合进行资源的释放的操作
            //conn,st,rs都是比较昂贵的资源,使用完毕之后,需要手动进行是否
            if(null!=rs){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if(null!=st){
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if(null!=conn){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return emp;
    }

    @Override
    public List<Emp> findAll() {

        //jdbc编程 - 面向接口编程
        Connection conn = null;

        Statement st = null;

        ResultSet rs = null;

        //新建一个集合对象
        List<Emp> empList = new ArrayList<>();

        //1. 注册驱动,但是从jdbc4.x规范开始,可以省略不写
        try {
            //如果想要切换db,此处只需要修改另外一个db的驱动类的全限定名即可.
            Class.forName("com.mysql.cj.jdbc.Driver");//alter+enter

            //2. 获取连接对象 - 设置一些连接参数
            //java代码顺利和db建立了链接 - jdbc代码 - mysql的客户端
            //每个db的url都是不一样的
            //url格式  主协议:次协议://db所在主机的ip地址:数据库的应用程序的端口号/数据库名称?key1=value1&key2=value2
            //String url="jdbc:mysql://localhost:3306/baby?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai";
            String url="jdbc:mysql://localhost:3306/baby";
            String user = "root";
            String password = "root";
            conn = DriverManager.getConnection(url,user,password);

            //3. 创建了语句对象
            st = conn.createStatement();

            //4. 执行sql - 将sql发送到mysql-server端进行sql语句的编译和解析
            String sql = "select id sid,first_name,salary from s_emp";

            //如果执行的是DQL语句 - 执行的是查询操作
            rs = st.executeQuery(sql);

            //5. 结果集对象的处理操作
            //while - 不知道循环多少次,但是知道循环退出的条件
            //rs结果集对象的本质是指向标题行的光标.调用next方法 - 希望光标向下移动一行
            //如果下一行有数据,则返回true,否则返回false
            while(rs.next()){
                //需要一行一行向下移动,还需要一列一列去取值
                //获取第一列 - 根据标题的名称
                Integer id = rs.getInt("sid");
                //根据列的序号进行获取,序号从1开始
                String name = rs.getString(2);
                //获取salary
                //float->double,尽量使用double/Double
                double salary = rs.getDouble(3);

                //OO - 创建了所谓的 - > 实体类
                // System.out.println(id+":"+name+":"+salary);

                //创建一个Emp对象 - 数据在内存中的载体 - 存储数据的"容器"
                //db设计 - 实体类对象
                Emp e = new Emp(id,name,salary);
                empList.add(e);

            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //6. 释放资源
            //无论try块中是否出现异常,都会执行,一般适合进行资源的释放的操作
            //conn,st,rs都是比较昂贵的资源,使用完毕之后,需要手动进行是否
            if(null!=rs){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if(null!=st){
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if(null!=conn){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

        return empList;
    }

    @Override
    public int delById(Integer id) {
        Connection conn = null;
        PreparedStatement pst = null;

        int count = 0;

        try {
            conn = JdbcUtil.getConnection();

            String sql = "delete from emp where id=?";
            pst = conn.prepareStatement(sql);
            pst.setInt(1,id);

            count = pst.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn,pst);
        }
        return count;
    }

    @Override
    public void saveMore(List<Emp> empList) {
        Connection conn = null;
        PreparedStatement pst = null;
        try {
            conn = JdbcUtil.getConnection();
            //创建语句对象
            //需要将带有参数的sql语句提前发送到mysql-server - 预编译和解析
            String sql = "insert into emp(first_name,salary) values(?,?)";
            pst = conn.prepareStatement(sql);
            //发送参数
            for (Emp emp : empList) {
                pst.setString(1,emp.getFirstName());
                pst.setDouble(2,emp.getSalary());

                //执行的DML操作[insert update delete]
                pst.executeUpdate();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn,pst);
        }
    }
}
